/**
 * Copying (c) Qixin Technoligies Co.,Ltd.2019-2029.all rights reserved.
 */

package com.example.configs;

import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.RedeliveryPolicy;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

import javax.jms.ConnectionFactory;

/**
 * 创  建   时  间： 2020/5/17
 * 版           本: V1.0
 * 作           者: qixin
 * 版  权   所  有: 版权所有(C)2019-2029
 * 公           司: 深圳市七智星科技有限公司
 */
@EnableJms
@SpringBootConfiguration
public class JMSConfiguration {

    /**
     * topic模式的ListenerContainer
     *
     * @param connection 连接工厂
     * @return ListenerContainer
     */
    @Bean
    public JmsListenerContainerFactory<?> jmsContainerFactory(
            @Qualifier("jmsConnectionFactory") ConnectionFactory connection){
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connection);
        factory.setPubSubDomain(true); // 设置消息模型 false：队列、true：发布/订阅
        factory.setSessionTransacted(true); // 事务处理
        // SESSION_TRANSACTED = 0    事务提交并确认
        // AUTO_ACKNOWLEDGE = 1    自动确认
        // CLIENT_ACKNOWLEDGE = 2    客户端手动确认
        // DUPS_OK_ACKNOWLEDGE = 3    自动批量确认
        // INDIVIDUAL_ACKNOWLEDGE = 4    单条消息确认 activemq 独有
        // 手动确认和单条消息确认需要手动的在客户端调用message.acknowledge()
        factory.setSessionAcknowledgeMode(ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE);
        // 设置连接数
        factory.setConcurrency("1-10");
        // 重连间隔时间
        factory.setRecoveryInterval(1000L);
        return factory;
    }

    /**
     * 消息重发机制
     *
     * @return 消息重发机制
     */
    @Bean
    public RedeliveryPolicy redeliveryPolicy(){
        RedeliveryPolicy redeliveryPolicy= new RedeliveryPolicy();
        // 是否在每次尝试重新发送失败后,增长这个等待时间
        redeliveryPolicy.setUseExponentialBackOff(true);
        // 重发次数,默认为6次这里设置为10次
        redeliveryPolicy.setMaximumRedeliveries(10);
        // 重发时间间隔,默认为1秒
        redeliveryPolicy.setInitialRedeliveryDelay(1);
        // 第一次失败后重新发送之前等待500毫秒,第二次失败再等待500 * 2毫秒,这里的2就是value
        redeliveryPolicy.setBackOffMultiplier(2);
        // 是否避免消息碰撞
        redeliveryPolicy.setUseCollisionAvoidance(false);
        // 设置重发最大拖延时间-1 表示没有拖延只有UseExponentialBackOff(true)为true时生效
        redeliveryPolicy.setMaximumRedeliveryDelay(-1);
        return redeliveryPolicy;
    }
}
